<!-- Copyright 2014 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// -->
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Unit Test of e2e.openpgp.KeyClient</title>
<script src="../../../../../javascript/closure/base.js"></script>
<script src="test_js_deps-runfiles.js"></script>
<script>
  goog.require('goog.array');
  goog.require('goog.net.XhrIo');
  goog.require('goog.string');
  goog.require('goog.testing.AsyncTestCase');
  goog.require('goog.testing.jsunit');
  goog.require('goog.testing.net.XhrIo');
  goog.require('goog.testing.PropertyReplacer');
  goog.require('e2e.async.Result');
  goog.require('e2e.cipher.all');
  goog.require('e2e.cipher.Aes');
  goog.require('e2e.cipher.Algorithm');
  goog.require('e2e.openpgp.block.TransferablePublicKey');
  goog.require('e2e.openpgp.block.factory');
  goog.require('e2e.openpgp.KeyClient');
  goog.require('e2e.hash.Sha1');
  goog.require('e2e.signer.Algorithm');
  goog.require('e2e.signer.Ecdsa');
</script>
</head>
<!--
:public key packet:
  version 4, algo 19, created 1408716939, expires 0
  unknown algorithm 19
:user ID packet: "<ecc@example.com>"
:signature packet: algo 19, keyid A91985B3AA980DC1
  version 4, created 1408716939, md5len 0, sigclass 0x10
  digest algo 8, begin of digest f9 06
  critical hashed subpkt 2 len 4 (sig created 2014-08-22)
  critical hashed subpkt 16 len 8 (issuer key ID A91985B3AA980DC1)
  unknown algorithm 19
:public sub key packet:
  version 4, algo 18, created 1408716939, expires 0
  unknown algorithm 18
:signature packet: algo 19, keyid A91985B3AA980DC1
  version 4, created 1408716939, md5len 0, sigclass 0x18
  digest algo 8, begin of digest 7d 8f
  critical hashed subpkt 2 len 4 (sig created 2014-08-22)
  critical hashed subpkt 16 len 8 (issuer key ID A91985B3AA980DC1)
  unknown algorithm 19
-->
<body>
<textarea id="pubKeyAscii" style="display:none">
-----BEGIN PGP PUBLIC KEY BLOCK-----
Charset: UTF-8

xv8AAABSBFP3UIsTCCqGSM49AwEHAgMEjt37zqFShFGWQs2XsjXe82RAjD0ULivh
wPVyqt/Bvn2eTTzWB9Bv5SDIaHI5m979ThVRRKlSMGQIiK2Il71wus3/AAAAETxl
Y2NAZXhhbXBsZS5jb20+wv8AAABmBBATCAAY/wAAAAWCU/dQi/8AAAAJkKkZhbOq
mA3BAAD5BgD/VVQ2Zjsv/pJeTRUeAjSB6k7tr1UyQneZ6/V1NHJZ0x8A/0lITTKZ
TZKyZLb+TejK9k9F7s0m9zZn4q4JxFWDbkOizv8AAABWBFP3UIsSCCqGSM49AwEH
AgMERvFPl1fK8weTLuZRhFkbC28BVFyW7WL5BoOZ0noaHsLb+GPpXSU4O9H593Bw
uYpu0ZNL7ueWkyFJPuNFGyG4lwMBCAfC/wAAAGYEGBMIABj/AAAABYJT91CL/wAA
AAmQqRmFs6qYDcEAAH2PAQD4vU9agaX1njxMXgF8nsqGAu1UWF+2M0t/JVQ9+YFC
hwEA1RFEzURGNJbObccP6oJGdBdL0A6YpZNLI2hXyISsU2A=
=taNi
-----END PGP PUBLIC KEY BLOCK-----
</textarea>
<script>
//<![CDATA[
var asyncTestCase = goog.testing.AsyncTestCase.createAndInstall(document.title);

// :public key packet:
//     version 4, algo 1, created 1415736191, expires 0
//     pkey[0]: [1024 bits]
//     pkey[1]: [17 bits]
//     keyid: 9D5B4273A2D3A7E8
// :user ID packet: "testkey <testkey@key.server>"

var keyText = goog.string.urlEncode(goog.array.flatten(
    '-----BEGIN PGP PUBLIC KEY BLOCK-----',
    'Charset: UTF-8',
    '',
    'xv8AAACNBFRia38BBAC0DdZTANfhMM1JcXEqYC3QBV2ibJ1F+OWSrPQVnC6Q/wqM',
    'Hq9tHgCu8c6UuDFuo6PlGDZu7ERHY0vcOqOPtw4+I4yo0HZ64LU0VGBbYjTlwwgJ',
    'pDjqCj6l0UW248BBkaJ8/0YUdcQRCqiciJJd0ssIBi/1GspsemY+yrVRzIg5BwAR',
    'AQABzf8AAAAcdGVzdGtleSA8dGVzdGtleUBrZXkuc2VydmVyPg==',
    '=4WG6',
    '-----END PGP PUBLIC KEY BLOCK-----',
    '').join('\r\n'));

/** @type {goog.testing.PropertyReplacer} */
var stubs = new goog.testing.PropertyReplacer();
var keyClient = new e2e.openpgp.KeyClient('http://127.0.0.1:8888');
var keyModulus = [0xb4, 0x0d, 0xd6, 0x53, 0x00, 0xd7, 0xe1, 0x30,
                  0xcd, 0x49, 0x71, 0x71, 0x2a, 0x60, 0x2d, 0xd0,
                  0x05, 0x5d, 0xa2, 0x6c, 0x9d, 0x45, 0xf8, 0xe5,
                  0x92, 0xac, 0xf4, 0x15, 0x9c, 0x2e, 0x90, 0xff,
                  0x0a, 0x8c, 0x1e, 0xaf, 0x6d, 0x1e, 0x00, 0xae,
                  0xf1, 0xce, 0x94, 0xb8, 0x31, 0x6e, 0xa3, 0xa3,
                  0xe5, 0x18, 0x36, 0x6e, 0xec, 0x44, 0x47, 0x63,
                  0x4b, 0xdc, 0x3a, 0xa3, 0x8f, 0xb7, 0x0e, 0x3e,
                  0x23, 0x8c, 0xa8, 0xd0, 0x76, 0x7a, 0xe0, 0xb5,
                  0x34, 0x54, 0x60, 0x5b, 0x62, 0x34, 0xe5, 0xc3,
                  0x08, 0x09, 0xa4, 0x38, 0xea, 0x0a, 0x3e, 0xa5,
                  0xd1, 0x45, 0xb6, 0xe3, 0xc0, 0x41, 0x91, 0xa2,
                  0x7c, 0xff, 0x46, 0x14, 0x75, 0xc4, 0x11, 0x0a,
                  0xa8, 0x9c, 0x88, 0x92, 0x5d, 0xd2, 0xcb, 0x08,
                  0x06, 0x2f, 0xf5, 0x1a, 0xca, 0x6c, 0x7a, 0x66,
                  0x3e, 0xca, 0xb5, 0x51, 0xcc, 0x88, 0x39, 0x07];
var keyExponent = [0x01, 0x00, 0x01];
var keyFingerprint = [0x76, 0x57, 0x2f, 0x5b, 0x04,
                      0x51, 0x94, 0x8d, 0x7b, 0x40,
                      0x8f, 0x0a, 0x9d, 0x5b, 0x42,
                      0x73, 0xa2, 0xd3, 0xa7, 0xe8];
var userIdPacket = new e2e.openpgp.packet.UserId(
    'testkey <testkey@key.server>');
var key = e2e.openpgp.block.factory.parseBlock([
  new e2e.openpgp.packet.PublicKey(
    4, 1415736191, e2e.cipher.factory.get(
      e2e.cipher.Algorithm.RSA,
      {n: keyModulus, e: keyExponent}),
    keyFingerprint),
  userIdPacket
]);

function setUp() {
  stubs.replace(goog.net.XhrIo, 'send', goog.testing.net.XhrIo.send);
  stubs.replace(keyClient, 'getOpenIdCredentials_', function() {
    return e2e.async.Result.toResult({
      credentials: {postBody: 'x', requestUri: 'y'},
      port: {close: function() {}}});
  });
  stubs.replace(e2e.random, 'getRandomBytes', function() {
    return [0];
  });
  // Simulate that the user ID packet is correctly signed. We don't have the
  // private key material in the test to generate the signature.
  stubs.replace(key, 'getUserIds', function() {
    return [userIdPacket];
  });
}

function tearDown() {
  stubs.reset();
  goog.array.clear(goog.testing.net.XhrIo.getSendInstances());
}

function testAddPublicKeyOKStatusCode() {
  var result = keyClient.importPublicKey(key);
  var xhrios = goog.testing.net.XhrIo.getSendInstances();
  assertEquals(1, xhrios.length);
  assertEquals('POST', xhrios[0].getLastMethod());
  assertEquals('http://127.0.0.1:8888/pks/add', xhrios[0].getLastUri());
  assertEquals(
    'keytext=' + keyText +'&nonce=00&requestUri=y&postBody=x', xhrios[0].getLastContent());
  asyncTestCase.waitForAsync('Waiting for response to be processed.');
  xhrios[0].simulateResponse(200, '');
  result.addCallback(function(isSucceeded) {
    assertEquals(true, isSucceeded);
    asyncTestCase.continueTesting();
  });
}

function testAddPublicKeyNotOKStatusCode() {
  var result = keyClient.importPublicKey(key);
  var xhrios = goog.testing.net.XhrIo.getSendInstances();
  assertEquals(1, xhrios.length);
  assertEquals('POST', xhrios[0].getLastMethod());
  assertEquals('http://127.0.0.1:8888/pks/add', xhrios[0].getLastUri());
  assertEquals(
    'keytext=' + keyText +'&nonce=00&requestUri=y&postBody=x', xhrios[0].getLastContent());
  asyncTestCase.waitForAsync('Waiting for response to be processed.');
  xhrios[0].simulateResponse(500, '');
  result.addCallback(function(isSucceeded) {
    assertEquals(false, isSucceeded);
    asyncTestCase.continueTesting();
  });
}

function testSearchPublicKeyFoundValidKey() {
  var email = 'test@google.com';
  var pubKeys = keyClient.searchPublicKey(email);
  var xhrios = goog.testing.net.XhrIo.getSendInstances();
  assertEquals(1, xhrios.length);
  assertEquals('GET', xhrios[0].getLastMethod());
  assertEquals(
      'http://127.0.0.1:8888/pks/lookup?op=get&x-email=test%40google.com',
      xhrios[0].getLastUri());
  asyncTestCase.waitForAsync('Waiting for response to be processed.');
  xhrios[0].simulateResponse(200, document.getElementById('pubKeyAscii').value);
  pubKeys.addCallback(function(pubKeys) {
    assertEquals(1, pubKeys.length);
    assertEquals('<ecc@example.com>', pubKeys[0].getUserIds()[0]);
    asyncTestCase.continueTesting();
  });
}

function testSeachPublicKeyFoundInvalidKey() {
  var email = 'test@google.com';
  var pubKeys = keyClient.searchPublicKey(email);
  var xhrios = goog.testing.net.XhrIo.getSendInstances();
  assertEquals(1, xhrios.length);
  assertEquals('GET', xhrios[0].getLastMethod());
  assertEquals(
      'http://127.0.0.1:8888/pks/lookup?op=get&x-email=test%40google.com',
      xhrios[0].getLastUri());
  asyncTestCase.waitForAsync('Waiting for response to be processed.');
  xhrios[0].simulateResponse(200, 'invalid key');
  pubKeys.addCallback(function(pubKeys) {
    assertArrayEquals([], pubKeys);
    asyncTestCase.continueTesting();
  });
}


function testSearchPublicKeyNotFound() {
  var email = 'test@google.com';
  var pubKeys = keyClient.searchPublicKey(email);
  var xhrios = goog.testing.net.XhrIo.getSendInstances();
  assertEquals(1, xhrios.length);
  assertEquals('GET', xhrios[0].getLastMethod());
  assertEquals(
      'http://127.0.0.1:8888/pks/lookup?op=get&x-email=test%40google.com',
      xhrios[0].getLastUri());
  asyncTestCase.waitForAsync('Waiting for response to be processed.');
  xhrios[0].simulateResponse(400, '');
  pubKeys.addCallback(function(pubKeys) {
    assertArrayEquals([], pubKeys);
    asyncTestCase.continueTesting();
  });
}
//]]>
</script>
</body>
</html>

